org 0x7c00

jmp boot_start
%include "load_inc.asm"

STACK_BASE equ 0x7C00
TRANS_SECT_NR equ 2
SECT_BUF_SIZE equ TRANS_SECT_NR * 512

disk_address_packet: db 0x10
	db 0
	db TRANS_SECT_NR
	db 0
	dw 0
	dw SUPER_BLK_SEG
	dd 0
	dd 0

err:
	mov dh, 3
	call disp_str
	jmp $

boot_start:
	mov ax, cs
	mov ds, ax
	mov es, ax
	mov ss, ax
	mov sp, STACK_BASE

	call clear_screen

	mov dh, 0
	call disp_str

	mov dword [disk_address_packet + 8], ROOT_BASE + 1
	call read_sector
	mov ax, SUPER_BLK_SEG
	mov fs, ax

	mov dword [disk_address_packet + 4], LOADER_OFF
	mov dword [disk_address_packet + 6], LOADER_SEG

	mov eax, [fs:SB_ROOT_INODE]
	call get_inode

	mov dword [disk_address_packet + 8], eax
	call read_sector

	mov si, LoaderFileName
	push bx

.str_cmp:
	add bx, [fs:SB_DIR_ENT_FNAME_OFF]
.1:
	lodsb
	cmp al, byte [es:bx]
	jz .2
	jmp .different
.2:
	cmp al, 0
	jz .found
	inc bx
	jmp .1

.different:
	pop bx
	add bx, [fs:SB_DIR_ENT_SIZE]
	sub ecx, [fs:SB_DIR_ENT_SIZE]
	jz .not_found

	mov dx, SECT_BUF_SIZE
	cmp bx, dx
	jge .not_found

	push bx
	mov si, LoaderFileName
	jmp .str_cmp
.not_found:
	mov dh, 2
	call disp_str
	jmp $

.found:
	pop bx
	add bx, [fs:SB_DIR_ENT_INODE_OFF]
	mov eax, [es:bx]
	call get_inode
	mov dword [disk_address_packet + 8], eax
load_loader:
	call read_sector
	cmp ecx, SECT_BUF_SIZE
	jl .done
	sub ecx, SECT_BUF_SIZE
	add word [disk_address_packet + 4], SECT_BUF_SIZE
	jc err
	add dword [disk_address_packet + 8], TRANS_SECT_NR
	jmp load_loader
.done:
	mov dh, 1
	call disp_str
	jmp LOADER_SEG:LOADER_OFF
	jmp $


LoaderFileName db "hdldr.bin", 0
MessageLength equ 9
BootMessage: db "Booting  "
Message1 db "HD Boot  "
Message2 db "No LOADER"
Message3 db "Error 0  "

clear_screen:
	mov ax, 0x600
	mov bx, 0x700
	mov cx, 0
	mov dx, 0x184f
	int 0x10
	ret

disp_str:
	mov ax, MessageLength
	mul dh
	add ax, BootMessage
	mov bp, ax
	mov ax, ds
	mov es, ax
	mov cx, MessageLength
	mov ax, 0x1301
	mov bx, 0x7
	mov dl, 0
	int 0x10
	ret

read_sector:
	xor ebx, ebx
	mov ah, 0x42
	mov dl, 0x80
	mov si, disk_address_packet
	int 0x13

	mov ax, [disk_address_packet + 6]
	mov es, ax
	mov bx, [disk_address_packet + 4]
	ret

get_inode:
	dec eax
	mov bl, [fs:SB_INODE_SIZE]
	mul bl
	mov edx, SECT_BUF_SIZE
	sub edx, dword [fs:SB_INODE_SIZE]
	cmp eax, edx
	jg err
	push eax

	mov ebx, [fs:SB_NR_IMAP_SECTS]
	mov edx, [fs:SB_NR_SMAP_SECTS]
	lea eax, [ebx + edx + ROOT_BASE + 2]
	mov dword [disk_address_packet + 8], eax
	call read_sector

	pop eax

	mov edx, dword [fs:SB_INODE_ISIZE_OFF]
	add edx, ebx
	add edx, eax
	mov ecx, [es:edx]

	add ax, word [fs:SB_INODE_START_OFF]

	add bx, ax
	mov eax, [es:bx]
	add eax, ROOT_BASE
	ret

times 510 - ($-$$) db 0
dw 0xaa55
